package im.composer.media.sound.codec;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.spi.AudioFileReader;

import net.sourceforge.jaad.adts.ADTSDemultiplexer;
import net.sourceforge.jaad.spi.javasound.MP4AudioInputStream;

public class AACFileReader  extends AudioFileReader {

	public static final AudioFileFormat.Type AAC = new AudioFileFormat.Type("AAC", "aac");
	public static final AudioFileFormat.Type MP4 = new AudioFileFormat.Type("MP4", "mp4");
	private static final AudioFormat.Encoding AAC_ENCODING = new AudioFormat.Encoding("AAC");
	
	
	@Override
	public AudioFileFormat getAudioFileFormat(InputStream in) throws UnsupportedAudioFileException, IOException {
		final byte[] b = new byte[8];
		in.read(b);
		if(new String(b, 4, 4).equals("ftyp")){
			final AudioFormat format = new AudioFormat(AAC_ENCODING, AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED, true);
			return new AudioFileFormat(AAC, format, AudioSystem.NOT_SPECIFIED);			
		}
		else {
			try {
				ADTSDemultiplexer adts = new ADTSDemultiplexer(in);
				AudioFormat format = new AudioFormat(AAC_ENCODING, adts.getSampleFrequency(), AudioSystem.NOT_SPECIFIED, adts.getChannelCount(), AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED, true);
				return new AudioFileFormat(AAC, format, AudioSystem.NOT_SPECIFIED);
			}
			catch(Exception e) {
			}
		}
		throw new UnsupportedAudioFileException();
	}

	@Override
	public AudioFileFormat getAudioFileFormat(URL url) throws UnsupportedAudioFileException, IOException {
		return getAudioFileFormat(url.openStream());
	}

	@Override
	public AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException {
		return getAudioFileFormat(new FileInputStream(file));
	}

	@Override
	public AudioInputStream getAudioInputStream(InputStream in) throws UnsupportedAudioFileException, IOException {
		try {
			in.mark(1000);
			return new MP4AudioInputStream(in, null, AudioSystem.NOT_SPECIFIED);
		}
		catch(IOException e) {
			in.reset();
			throw e;
		}
	}

	@Override
	public AudioInputStream getAudioInputStream(URL url) throws UnsupportedAudioFileException, IOException {
		return getAudioInputStream(url.openStream());
	}

	@Override
	public AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException {
		return getAudioInputStream(new FileInputStream(file));
	}

}
